//****************************************************
// Porman Project 2
// Filename: CLogger.h
// Date: 2011/05/07
// Author: KengYu Lin
// Modify:
//****************************************************
#ifndef _CLOGGER_H
#define _CLOGGER_H
#include <map>
#include "CGLDef.h"

namespace Porman
{

namespace GL
{

enum LogLevel
{
    LOG_ERROR,
    LOG_WARNING,
    LOG_INFO,
    LOG_DEBUG,
    LOG_DEBUG1,
    LOG_DEBUG2,
    LOG_DEBUG3,
    LOG_DEBUG4
};

//-----------------------------
// class ILogReceiver:
//-----------------------------
class ILogReceiver
{
public:
    ILogReceiver( void ) : m_bEnable(true) {}
    virtual ~ILogReceiver( void ) {}
    virtual bool onLog( const std::string& sLevel, const std::string& sSender, const std::string& sMsg, int iLine ) = 0;

    bool isEnable( void ) { return m_bEnable; }
    void setEnable( bool bEnable ) { m_bEnable = bEnable; }

private:
    bool m_bEnable;
};

class CConsoleLogReceiver : public ILogReceiver
{
public:
    CConsoleLogReceiver( void ) {}
    virtual ~CConsoleLogReceiver( void ) {}
    virtual bool onLog( const std::string& sLevel, const std::string& sSender, const std::string& sMsg, int iLine );
};

//-----------------------------
// class CLogger:
//-----------------------------
class CLogger : public CSingletonT<CLogger>
{
public:
    PGL_API CLogger( void );
    PGL_API virtual ~CLogger( void );

    PGL_API void log( LogLevel level, const std::string& sSender, const std::string& sMsg, int iLine );
    PGL_API void setLogLevel( LogLevel level );
    PGL_API LogLevel getLogLevel( void );
    PGL_API void registerLogReceiver( ILogReceiver* pReceiver, const std::string& sName );
    PGL_API bool removeLogReceiver( const std::string& sName );
    PGL_API bool isLogReceiverRegistered( const std::string& sName );
    PGL_API ILogReceiver* getLogReceiver( const std::string& sName );

private:
    LogLevel m_enumCurLogLevel;
    std::map<std::string, ILogReceiver*> m_mapLogReceiver;
    CConsoleLogReceiver m_ConsoleReveiver;
    IMutex* m_pMutex;
};

#define LOG_ERROR( Msg )   CLogger::getSingletonPtr()->log( LOG_ERROR, __FILE__, Msg, __LINE__ )
#define LOG_WARNING( Msg ) CLogger::getSingletonPtr()->log( LOG_WARNING, __FILE__, Msg, __LINE__ )
#define LOG_INFO( Msg )    CLogger::getSingletonPtr()->log( LOG_INFO, __FILE__, Msg, __LINE__ )
#define LOG_DEBUG( Msg )   CLogger::getSingletonPtr()->log( LOG_DEBUG, __FILE__, Msg, __LINE__ )
#define LOG_DEBUG1( Msg )  CLogger::getSingletonPtr()->log( LOG_DEBUG1, __FILE__, Msg, __LINE__ )
#define LOG_DEBUG2( Msg )  CLogger::getSingletonPtr()->log( LOG_DEBUG2, __FILE__, Msg, __LINE__ )
#define LOG_DEBUG3( Msg )  CLogger::getSingletonPtr()->log( LOG_DEBUG3, __FILE__, Msg, __LINE__ )
#define LOG_DEBUG4( Msg )  CLogger::getSingletonPtr()->log( LOG_DEBUG4, __FILE__, Msg, __LINE__ )

}//End namespace GL

}//End nsmespace Porman

#endif